package com.sunday.player.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.widget.Toast;

import com.sunday.player.Activity_Player;
import com.sunday.player.domain.musicData;
import com.sunday.player.util.playerControl;
/**
 * 서비스에서 처리해야 하는상황
 * 1 . 전화올때
 * 2 . 미디어 키 
 * 3 . 이어폰 헤드셋 뽑았다 킬때 
 * @author user
 *
 */
public class PlayerService extends Service implements Runnable{
    private final String TAG ="mPlayer.getDuration()";
    private MediaPlayer mPlayer;
  
    private int currentMusicIndex = 0;
    private List<musicData> MusicList = new ArrayList<musicData>();
    private NotificationManager notificationManager;
    private Notification 	notificationPlayer ;
    private final Notification mNtManager = new Notification();
    
    private final int NotificationPlayID = 100000;
    
    public static final int MUSICTYPE_NOT = -1;
    public static final int MUSICTYPE_MP3 = 0;
    public static final int MUSICTYPE_STRAM = 1;
   
    public static final int PLAYER_STOP = 0;
    public static final int PLAYER_PLAY = 1;
    public static final int PLAYER_NEXT = 2;
    public static final int PLAYER_PRIV = 3;
    
    
    /**
     * 잠시 정지인가 ?
     */
    private boolean isPause = false;
    private RemoteCallbackList<musicplayerCallBack> callBacks = new RemoteCallbackList<musicplayerCallBack>();
    private final musicservicecontrol.Stub mBinder = new musicservicecontrol.Stub() {

	@Override
	public boolean Control_play() throws RemoteException {
	    
	    playerControl.showToast(PlayerService.this, "Control_play");
	    try {
		    return PlayerService.this.SelectPlay( currentMusicIndex);
	    } catch (Exception e) {
		e.printStackTrace();
		return false;
	    }
	   
	}

	@Override
	public void Control_pause() throws RemoteException {
	    playerControl.showToast(PlayerService.this, "Control_pause");
	    PlayerService.this.Control_pause();
	}

	@Override
	public void Control_next() throws RemoteException {
	    playerControl.showToast(PlayerService.this, "Control_next");
	    PlayerService.this.Control_next();
	}

	@Override
	public void Control_prev() throws RemoteException {
	    playerControl.showToast(PlayerService.this, "Control_prev"); 
	    
	    PlayerService.this.Control_prev();
	}
	
	@Override
	public musicData getTrackData() throws RemoteException {
	    if(currentMusicIndex < 0 || MusicList.size() < currentMusicIndex){
		return null;
	    }
	    
	    
	    return MusicList.get(currentMusicIndex);
	}

	@Override
	public void SelectPlay(int ListIndex, int itemIndex)throws RemoteException {
	    PlayerService.this.SelectPlay( itemIndex);
	    
	}

	@Override
	public boolean isPlaying() throws RemoteException {
	    if(mPlayer != null){
		return mPlayer.isPlaying();
	    }
	    return false;
	}

	@Override
	public int getPosition() throws RemoteException {
	    if(mPlayer == null){
		return 0;
	    }
	    return mPlayer.getCurrentPosition();
	}
	
	@Override
	public List<musicData> getMusicList() throws RemoteException {
	    return MusicList;
	}

	@Override
	public int getplayPosition() throws RemoteException {
	    return currentMusicIndex;
	}

	@Override
	public void setupCallback(musicplayerCallBack incallBack)
		throws RemoteException {
	    
	    if(incallBack != null){
		if(callBacks.beginBroadcast() < 1){
		    callBacks.register(incallBack);
			    
		}
		callBacks.finishBroadcast();
		
	    }
	    
	}

	@Override
	public void setPlayerPosition(int Position) throws RemoteException {
	    if(mPlayer != null){
		playerControl.Trace_i("Position = "+Position+"		mPlayer.getDuration() = "+mPlayer.getDuration(), TAG);
		int position = Position * 1000;
		mPlayer.seekTo(position);
	    }
	}

	@Override
	public void removeCallback(musicplayerCallBack incallBack)
		throws RemoteException {
	    if(incallBack != null){
		callBacks.unregister(incallBack);
	    }
	    
	}

	@Override
	public musicData getTrackDatatoIndex(int index) throws RemoteException {
	    if(MusicList.size() < index){
		return null;
	    }
	    return MusicList.get(index);
	}
    
    };
    
    
   
    OnPreparedListener preparedListener = new OnPreparedListener() {
	@Override
	public void onPrepared(MediaPlayer media) {
		mPlayer.start();
	}
    };
    OnCompletionListener complete_listener = new OnCompletionListener() {

	@Override
	public void onCompletion(MediaPlayer mp) {
	    playerControl.trace("E","onCompletion");
	    
	    
	    Control_next();
	}
    };
    OnBufferingUpdateListener bufListener = new OnBufferingUpdateListener() {
	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		// 버퍼율
	}

    };
    /**
     * 플레이어 초기화
     */
    private void InitPlayer(){
	
	mPlayer = new MediaPlayer();
	mPlayer.setOnPreparedListener(preparedListener);
	mPlayer.setOnCompletionListener(complete_listener);
	mPlayer.setOnBufferingUpdateListener(bufListener);
	mPlayer.setOnInfoListener(infoListener);
	mPlayer.setOnErrorListener(errorListener);
	mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
	isPause = false;
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if(mPlayer != null){
	    Control_Stop();

            mPlayer.release();
        }
    }
    private void Control_play(musicData item){
	playerControl.trace("i", "Control_play = "+item.getTitle());
	playerControl.trace("i", "Control_play = "+item.get_data());
	
	
	
	
	if(mPlayer == null){
	    InitPlayer();
	}
	if(isPause){
	    // 잠시 멈춤 상태라면 재생
	    mPlayer.start();
	    sendPlayerState(PLAYER_PLAY);
	    return;
	}
	if(mPlayer.isPlaying()){
	    Control_Stop();

	   
	}
	try {
	    mPlayer.reset();
	    mPlayer.setDataSource(item.get_data());
	    mPlayer.prepareAsync();
	    
	    showNotification(item);
	    startForeground(NotificationPlayID, mNtManager);
	    sendPlayerState(PLAYER_PLAY);
	    
	} catch (IllegalArgumentException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (IllegalStateException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} 
    }
    /**
     * 선택한곡 플레이 
     * @param ListIndex
     * @param musicIndex
     */
    private boolean SelectPlay(int musicIndex){
	if(musicIndex == currentMusicIndex){
	    if(mPlayer != null && mPlayer.isPlaying()){
		// 재생중인 곡을일경우 동작안함 
		return false;
	    }
	}
	
	currentMusicIndex = musicIndex;
	playerControl.trace("e","SelectPlay = "+currentMusicIndex);
	playerControl.trace("e","checkFileType = "+checkFileType(MusicList.get(currentMusicIndex))  );
	
	
	
	
	isPause = false;
	
	
	
	
	if(MusicList.size() == 0){
	    
	    currentMusicIndex = -1;
	    // 재생목록이 없음
	    return false;
	}
	if(checkFileType(MusicList.get(currentMusicIndex)) != MUSICTYPE_NOT){
		Control_play(MusicList.get(musicIndex));
	}
	return true;
    }
    
    
    /**
     * 파일인지 아니면 스트리밍을 해야하는지 체크 
     * 
     */
    public int checkFileType(musicData data){
	playerControl.trace("e","---------checkFileType--------------------");
	if(data == null) return MUSICTYPE_NOT;
	try {
		if(data.get_data() != null){
		    if(new File(data.get_data()).isFile()){
			return MUSICTYPE_MP3;
		    }else{
			return MUSICTYPE_NOT;
		    }
		}else 
		if(data.getUrl() != null){
		   
			return MUSICTYPE_STRAM;
		    
		}
	    
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return MUSICTYPE_NOT;
	
    }
    
    
    private void Control_pause( ){
	isPause = true;
	if(mPlayer.isPlaying()){
	    mPlayer.pause();
	}
	sendPlayerState(PLAYER_STOP);
    }
    private void Control_Stop( ){
	isPause = true;
	if(mPlayer.isPlaying()){
	    mPlayer.stop();
	}
	sendPlayerState(PLAYER_STOP);
    }
    private void Control_next( ){
	isPause = false;
	if(mPlayer != null && mPlayer.isPlaying()){
	    Control_Stop();
	}
	
	
	if(MusicList.size() == 0){
	   
	    currentMusicIndex = 0;
	    // 재생목록이 없음
	    playerControl.trace("e","재생목록이 없음 = ");
	    //InitTesat();
	    return;
	}

	// 다음 재생 위치 계산
	boolean isNext = true;
	int MaxCount = 0;
	do{
	    currentMusicIndex ++;
	    // 아이템
	    if(MusicList.size() <= currentMusicIndex){
    	    	currentMusicIndex = 0;
	    }
	    if(checkFileType(MusicList.get(currentMusicIndex)) != MUSICTYPE_NOT){
		isNext = false;
		SelectPlay( currentMusicIndex);
	    }
	    MaxCount ++;
	    if(MaxCount > MusicList.size() ){
		isNext = false;
		Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT).show();
	    }
	    
	}while(isNext);
	
	
	
	
	
		
	
    
    
    }
    
    
  
    private void Control_prev( ){
	isPause = false;

	if(mPlayer != null && mPlayer.isPlaying()){
	    Control_Stop();
	}
	// 다음 재생 위치 계산
	
	
	if(MusicList.size() == 0){
	    currentMusicIndex = 0;
	    return;
	}
	// 다음 재생 위치 계산
		boolean isNext = true;
		int MaxCount = 0;
		do{
		    currentMusicIndex --;
		    // 아이템
		if(currentMusicIndex < 0){
			   
			currentMusicIndex = MusicList.size()-1;
		} 
		if(checkFileType(MusicList.get(currentMusicIndex)) != MUSICTYPE_NOT){
		    isNext = false;
		    SelectPlay( currentMusicIndex);
		}
		    MaxCount ++;
		    if(MaxCount > MusicList.size() ){
			isNext = false;
			Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT).show();
		    }
		    
		}while(isNext);
		
		
	
	
	
	SelectPlay( currentMusicIndex);
    }

    OnInfoListener infoListener = new OnInfoListener() {

	@Override
	public boolean onInfo(MediaPlayer mp, int what, int extra) {
	    playerControl.trace("E","onInfo"+ what +" + "+extra );
		switch(what) {
			case MediaPlayer.MEDIA_INFO_UNKNOWN:
				playerControl.trace("E","MEDIA_INFO_UNKNOWN");
				break;
			case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:

			    	playerControl.trace("E","MEDIA_INFO_BAD_INTERLEAVING");
				break;
			case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:

			    	playerControl.trace("E","MEDIA_INFO_NOT_SEEKABLE");
				break;
			case 701:
			    	playerControl.trace("E","MEDIA_INFO_BUFFERING_START");
			    	break;
			case 702:
			    	playerControl.trace("E","MEDIA_INFO_BUFFERING_END");
				break;
		}

		return false;
	}
    };
    
    OnErrorListener errorListener = new OnErrorListener() {

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
	    playerControl.trace("E","onError"+ what +" + "+extra );
	    switch (what) {
	    case 1:
		
		break;
	    case -32:
		// 무시함 
		break;
	    default:
		    Control_pause();
		break;
	    }
	    return false;
	}
	
    };
    public void onStart(Intent intent, int startId) {
	playerControl.trace("e","onStart");
	setForeground(true);
    };
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
	
	playerControl.trace("e","onStartCommand");
	//InitPlayer();
	//InitTesat();
	//InitNotification();
	//setForeground(true);
	startForeground(NotificationPlayID, mNtManager);
        return Service.START_NOT_STICKY;
    }
    
 
    
    
    
    @Override
    public IBinder onBind(Intent arg0) {
	  playerControl.trace("i", "onBind");
	return mBinder;
    }
    private void showNotification(musicData item){
	if(notificationPlayer == null){
	    InitNotification();
	}
	Intent startPlayer = new Intent(this, Activity_Player.class);
	startPlayer.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
	PendingIntent start = PendingIntent.getActivity(PlayerService.this, 0, startPlayer, PendingIntent.FLAG_UPDATE_CURRENT);
	notificationPlayer.setLatestEventInfo(this,item.getTitle(), item.get_data(), start);
	notificationManager.notify(NotificationPlayID, notificationPlayer);
	
	
    }
    /**
     * player 노티 초기화
     */
    private void InitNotification(){
	if(notificationManager == null){
	    notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
	}
	notificationPlayer = new Notification(android.R.drawable.ic_media_play, "플레이중", 0);
	notificationPlayer.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT ;
	
	
	
	
    }
    private void sendPlayerState(int state){
	try {
	    int N = callBacks.beginBroadcast();
	    playerControl.Trace_i("sendPlayerState = "+N, TAG);
		
	    for(int a = 0 ; a < N ; a++){
		    callBacks.getBroadcastItem(a).ReceivePlayerState(state);
	    }
	    callBacks.finishBroadcast();   
	} catch (Exception e) {
	   e.printStackTrace();
	}
	
    }
    
    
    @Override
    public void run() {
	// TODO Auto-generated method stub
	
    }
    
    
}
